<?php

class NCore_Dataset implements ArrayAccess, Iterator, Countable
{
	// great writeup pertaining to this type of code http://www.sitepoint.com/print/php5-standard-library
	protected $valid = FALSE;
	protected $rows = array();

    function __construct($arr = NULL)
    {
        if (!is_null($arr))
        {
            foreach ($arr as $row)
            {
                if (!$row instanceof NCore_Row)
                {
                    throw new Exception('The items of the array passed to the NCore_Dataset construtor must all be of type NCore_Row');
                }
                else
                {
                    $this->rows[] = $row;
                }
            }
        }
    }

	/** 
	* Defined by ArrayAccess interface 
	* Set a value given it's key e.g. $A['title'] = 'foo'; 
	* @param mixed key (string or integer) 
	* @param mixed value 
	* @return void 
	*/ 
	function offsetSet($key, $value)
	{ 
		if(!$value instanceof NCore_Row)
			throw new Exception('Datasets only store objects of type NCore_Row.');
			
		if(is_null($key))
		{
			$this->rows[] = $value;
		}
		else
		{
			$this->rows[$key] = $value;
		}
	} 
	/** 
	* Defined by ArrayAccess interface 
	* Return a value given it's key e.g. echo $A['title']; 
	* @param mixed key (string or integer) 
	* @return mixed value 
	*/ 
	function offsetGet($key)
	{ 
		return $this->rows[$key];
	} 
	/** 
	* Defined by ArrayAccess interface 
	* Unset a value by it's key e.g. unset($A['title']); 
	* @param mixed key (string or integer) 
	* @return void 
	*/ 
	function offsetUnset($key) { 
		if(array_key_exists($key, $this->rows)) 
		{ 
			unset($this->rows[$key]);
		} 
	} 
	/** 
	* Defined by ArrayAccess interface 
	* Check value exists, given it's key e.g. isset($A['title']) 
	* @param mixed key (string or integer) 
	* @return boolean 
	*/ 
	function offsetExists($offset)
	{ 
		return isset($this->rows[$offset]); 
	} 
	function current()
	{
		return current($this->rows);
	}
	function key(){
		return key($this->rows);
	}
	function next()
	{
		$this->valid = (FALSE !== next($this->rows)); 
	}
	function rewind()
	{
		$this->valid = (FALSE !== reset($this->rows)); 
	}
	function valid()
	{
		return $this->valid;
	}
	public function count()
	{
		return count($this->rows);
	}
	public function fill($arr)
	{
		$this->rows = $arr;
	}
}

?>